﻿// Decompiled with JetBrains decompiler
// Type: Netick.NativeUDPSocket
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using NanoSockets;
using System;
using System.Runtime.CompilerServices;
using System.Text;

#nullable disable
namespace Netick;

public class NativeUDPSocket : INetickSocket
{
  private Socket _socket;
  private StringBuilder _ip = new StringBuilder(1025);
  private static bool _isInitialized;

  public IEndPoint CreateFromIpPort(string ip, int port)
  {
    Address address = new Address();
    int num = (int) UDP.SetIP(ref address, ip);
    address.port = (ushort) port;
    return (IEndPoint) address;
  }

  public bool Initialize()
  {
    if (NativeUDPSocket._isInitialized)
      return true;
    NativeUDPSocket._isInitialized = true;
    return UDP.Initialize() == Status.OK;
  }

  /// --------------------------------------------------------------------------------------------------------------
  ///             --------------------------------------------------------------------------------------------------------------
  ///             --------------------------------------------------------------------------------------------------------------
  ///             --------------------------------------------------------------------------------------------------------------
  public void Deinitialize()
  {
    if (!NativeUDPSocket._isInitialized)
      return;
    NativeUDPSocket._isInitialized = false;
    UDP.Deinitialize();
  }

  public void Shutdown()
  {
    if (!this._socket.IsCreated)
      return;
    UDP.Destroy(ref this._socket);
  }

  public void StartClient(long sendBufferSize, long receiveBufferSize)
  {
    this._socket = UDP.Create((int) sendBufferSize, (int) receiveBufferSize);
    this.SetOptions();
  }

  public void StartServer(int port, long sendBufferSize, long receiveBufferSize)
  {
    this._socket = UDP.Create((int) sendBufferSize, (int) receiveBufferSize);
    Address address = new Address() { Port = (ushort) port };
    if (UDP.SetIP(ref address, "::0") != Status.OK)
      NetickLogger.LogError((object) "Netick Transport: setup failed.");
    if (UDP.Bind(this._socket, ref address) != 0)
      NetickLogger.LogError((object) "Netick Transport: setup failed.");
    this.SetOptions();
  }

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  private void SetOptions()
  {
    if (UDP.SetDontFragment(this._socket) != Status.OK)
      NetickLogger.LogError((object) "Netick Transport: setup failed.");
    if (UDP.SetNonBlocking(this._socket) == Status.OK)
      return;
    NetickLogger.LogError((object) "Netick Transport: setup failed.");
  }

  public bool Connect(ref IEndPoint address)
  {
    if (!this._socket.IsCreated)
      throw new Exception("Netick Transport: start client first");
    Address address1 = (Address) address;
    if (UDP.SetIP(ref address1, "::1") != Status.OK)
    {
      NetickLogger.LogError((object) "Netick Transport: setup failed.");
      return false;
    }
    if (UDP.Connect(this._socket, ref address1) != 0)
    {
      NetickLogger.LogError((object) "Netick Transport: setup failed.");
      return false;
    }
    address = (IEndPoint) address1;
    return true;
  }

  public int Poll() => UDP.Poll(this._socket, 0L);

  public unsafe int Receive(out IEndPoint address, byte* buffer, int bufferSize)
  {
    Address address1 = new Address();
    int num = UDP.Receive(this._socket, ref address1, new IntPtr((void*) buffer), bufferSize);
    if (num > 0)
    {
      int ip = (int) UDP.GetIP(ref address1, this._ip, this._ip.Capacity);
    }
    address = (IEndPoint) address1;
    return num;
  }

  public unsafe void Send(IEndPoint address, byte* data, int dataLength)
  {
    Address address1 = (Address) address;
    UDP.Send(this._socket, ref address1, new IntPtr((void*) data), dataLength);
  }
}
